

#include "CCMoveNode.h"
#include "device.h"

CCMoveNode* CCMoveNode::create()
{
    CCMoveNode * pRet = new CCMoveNode();
	pRet->autorelease();
	return pRet;
}

CCMoveNode::CCMoveNode(void):
mSender(NULL),
mDragBegan(NULL),
mDragMove(NULL),
mDragEnd(NULL),
mDragState(kDragStateUngrabbed),
mDragZoomIn(false),
mDragEnable(true)
{
    
}

CCMoveNode::~CCMoveNode(void)
{
    
}

CCRect CCMoveNode::rect()
{
    CCSize s = getContentSize();
    CCAssert(s.height > 0 && s.width > 0, "CCMoveNode content size is empty!!!");
    return CCRectMake(-s.width / 2, -s.height / 2, s.width, s.height);
}

void CCMoveNode::setToTop()
{
    CCNode* node = this->getParent();
    node->removeChild(this, true);
    node->addChild(this);
}

void CCMoveNode::onEnter()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
    CCNode::onEnter();
}

void CCMoveNode::onExit()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->removeDelegate(this);
    CCNode::onExit();
}

bool CCMoveNode::containsTouchLocation(CCTouch* touch)
{
    return rect().containsPoint(convertTouchToNodeSpaceAR(touch));
}

bool CCMoveNode::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
    if (!mDragEnable)
        return false;
    if (mDragState != kDragStateUngrabbed)
        return false;
    if (!containsTouchLocation(touch))
        return false;
    if (mDragBegan && mSender)
        (mSender->*mDragBegan)(this);
    setToTop();
    if (mDragZoomIn)
    {
        mCurrentScale = this->getScale();
        setScale(mCurrentScale + 0.1);
    }
    // 开始点击的touch点
    mTouchBegPos = touch->getLocation();
    // 记录开始点击时Node的初始位置
    mOriginPos = getPosition();
    CCLOG("touch beg pos(%f,%f)", touch->getLocation().x, touch->getLocation().y);
    mDragState = kDragStateGrabbed;
    return true;
}

void CCMoveNode::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
    CCPoint newPos;
    CCPoint offset;
    CCAssert(mDragState == kDragStateGrabbed, "CCMoveNode - Unexpected state!");
    CCPoint touchPoint = touch->getLocation();
    if (mDragZoomIn)
        setScale(mCurrentScale + 0.1);
    // 计算移动的偏移值
    offset.x = (touchPoint.x - mTouchBegPos.x);
    offset.y = (touchPoint.y - mTouchBegPos.y);
    // 设置新的位置
    newPos.x = mOriginPos.x + offset.x;
    newPos.y = mOriginPos.y + offset.y;
    // 
    if (newPos.y >= getParent()->getContentSize().height || newPos.y <= 0)
        return ;
    if (newPos.x >= getParent()->getContentSize().width || newPos.x <= 0)
        return ;
    setPosition(newPos);
    if (mDragMove && mSender)
        (mSender->*mDragMove)(this);
}

void CCMoveNode::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
    CCAssert(mDragState == kDragStateGrabbed, "CCMoveNode - Unexpected state!");
    mDragState = kDragStateUngrabbed;
    if (mDragZoomIn)
        this->setScale(mCurrentScale);
    if (mDragEnd && mSender)
        (mSender->*mDragEnd)(this);
}

CCObject* CCMoveNode::copyWithZone(CCZone *pZone)
{
    this->retain();
    return this;
}

void CCMoveNode::touchDelegateRetain()
{
    this->retain();
}

void CCMoveNode::touchDelegateRelease()
{
    this->release();
}

void CCMoveNode::setDragEnable(bool enable)
{
    mDragEnable = enable;
}

void CCMoveNode::setDragZoomIn(bool enable)
{
    mDragZoomIn = enable;
}

void CCMoveNode::setDragDropCallback(CCObject* pSender, SEL_CallFuncMoveNode dragBegan,
                                     SEL_CallFuncMoveNode dragMove, SEL_CallFuncMoveNode dragEnd)
{
    mSender = pSender;
    mDragBegan = dragBegan;
    mDragMove = dragMove;
    mDragEnd = dragEnd;
}

void CCMoveNode::setDragDropCallback(CCObject* pSender, SEL_CallFuncMoveNode dragDropEnd)
{
    mSender = pSender;
    mDragEnd = dragDropEnd;
}

void CCMoveNode::addBackgourdImage(const char* bkgName)
{
    CCSprite* image = CCSprite::create(bkgName);
    // 默认使用背景图作为Node大小
    CCAssert(image, "image is NULL");
    this->setContentSize(image->getTexture()->getContentSize());
    image->setPosition(ccp(0, 0));
    this->addChild(image);
}

void CCMoveNode::addFrameImage(const char* frameName)
{
    CCSprite* image = CCSprite::create(frameName);
    image->setPosition(ccp(0, 0));
    this->addChild(image);
}

void CCMoveNode::addMasterImage(const char* masterName)
{
    CCSprite* image = CCSprite::create(masterName);
    image->setPosition(ccp(0, 0));
    this->addChild(image);
}

void CCMoveNode::addBottomItem(const char* bottomName)
{
    CCSprite* image = CCSprite::create(bottomName);
    image->setPosition(ccp(0, 0));
    this->addChild(image);
}
